#!/usr/sbin/rsct/perl5/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# "@(#)94   1.19   src/rsct/registry/cli/bin/rmsrdir.perl, srcli, rsct_rpyxh, rpyxht1f3 2/22/01 16:25:26"
######################################################################
#                                                                    #
# Module: rmsrdir                                                    #
#                                                                    #
# Purpose:                                                           #
#   rmsrdir - Removes one or more directories from the System        #
#             Registry.                                              #
#                                                                    #
# Syntax:                                                            #
#   rmsrdir [-h] [-R] [-TV] Directory...                             #
#                                                                    #
# Flags:                                                             #
#   -h        Help. Writes this command's usage statement to stdout. #
#   -R        Permits a recursive removal of the named directory and #
#             its contents (tables and directories) provided that    #
#             none of the underlying tables are currently locked.    #
#   -T        Trace. Prints trace messages to stderr.                #
#   -V        Verbose. Prints verbose messages to stderr.            #
#                                                                    #
# Operands:                                                          #
#   Directory     The name of the directory in the system registry   #
#                 that we wan to remove.  More than one directory    #
#                 operand can be specified.  A relative or absolute  #
#                 directory can be specified.                        #
#                                                                    #
# Description:                                                       #
#   The rmsrdir command removes the directory specified by the       #
#   Directory operand from the System Registry. The directory must   #
#   be empty before you can remove it unless you have specified the  #
#   -r flag. You must have write permission on the parent directory  #
#   and all underlying parent directories when the -r flag is        #
#   specified for the directory to be removed. Use the srls command  #
#   to check whether the directory is empty.  If more than one       #
#   Directory operand is specified it is equivalent to the command   #
#   being invoked once for each directory.                           #
#                                                                    #
# Exit Values:                                                       #
#   0  SR_CLI_SUCCESS        Command completed successfully.         #
#   1  SR_CLI_REGISTRY_ERROR Command terminated due to an underlying #
#                            System Registry error.                  #
#   2  SR_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  SR_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   4  SR_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   5  SR_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            directory to be removed.                #
#                                                                    #
# Examples:                                                          #
#   1. To remove two directories non-recursively:                    #
#   rmsrdir /Cluster /Node                                           #
#                                                                    #
#   2. To remove the directory /test/samples recursively:            #
#   rmsrdir -R /test/samples                                         #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /usr/sbin/rsct/msgmaps/srcli.rmsrdir.map                         #
#                                                                    #
# Outputs:                                                           #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: $LSMSG                                                 #
#   Extensions:  CT::SR.pm CT::SRrc.pm                               #
#   Modules:  SR_cli_utils.pm, SR_cli_rc.pm                          #
#   Perl library routines: Getopt::Std                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000900 SAB 38317: Initial delivery.                              #
#                                                                    #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands.                          #
# B. Initialize a session with the system registry.                  #
# C. Loop through the list of directories, deleting each one.        #
# D. Terminate the session with the system registry and any other    #
#    necessary cleanup.                                              #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/usr/sbin/rsct/pm";
use locale;
use Getopt::Std; 

use CT_cli_utils qw(printIMsg
                    printEMsg
);

use CT::SRrc;
use CT::SR;
use CT::SRrc qw(SR_NO_DIRECTORY SR_NO_PERMISSION 
                SR_DIRECTORY_NOT_EMPTY
                SR_TABLES_LOCKED 
); 
use SR_cli_utils qw(init_session    term_session 
                    isRelative      printCEMsg
                    $DEFAULT_GLOBAL_MOUNT_POINT
                    error_exit      set_session_variables
);
use SR_cli_rc qw(:return_codes);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
# Constants
$TRUE           = 1;
$FALSE          = 0;

$Verbose        = $FALSE;            # Verbose turned off
$Trace          = $FALSE;            # Trace turned off
$Opt_Recursive  = $FALSE;            # Do not rm recursively

# Messaging Globals 
$PROGNAME       = "rmsrdir";         # Program Name for messages
$MSGCAT         = "srcli.cat";       # Message catalogue for this cmd
$CTDIR          = "/usr/sbin/rsct";  # Cluster directory path
$CTBINDIR       = "$CTDIR/bin";      # Cluster Bin directory path
$LSMSG          = "$CTBINDIR/ctdspmsg";  # Display message routine
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";   # Msg map path for $LSMSG  

%Cleanup = ();                       # Hash of items to cleanup
                                     # {Session} $session to term

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
my $Tree_handle    = "";
my @Directory      = ();
my @Dir            = ();             # Fully qualified directory names
my $Set_work_dir   = $FALSE;
my $Mount_point    = $DEFAULT_GLOBAL_MOUNT_POINT;  # Mount point      
my $rc             = 0;


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
# Parse the command line, exit if there are errors 
($rc, @Directory) = parse_cmd_line();
($rc == 0) || error_exit($rc);

# Determine if a relative mount point must be set, depending
# on whether any relative directories have been given on the
# command line.
# Fully qualifiy any absolute directory paths
my $index = 0;
foreach (@Directory) {
    ($holder, $Dir[$index]) = set_session_variables($_);
    if ($holder == $TRUE) { $Set_work_dir = $TRUE; }
    $index++;
}

# Establish a session
# CT::SR::open_tree, CT::SR::mount_directory, 
# CT::SR::change_current_directory
# Uses Env qw(CT_SR_HOME, CT_SR_NUM_RETRIES, CT_SR_TIMEOUT) if they 
# are set.
($rc, $Tree_handle) = init_session($Set_work_dir);
($rc == 0) || error_exit($rc);

# Add the tree handle to the cleanup hash
$Cleanup{Session} = $Tree_handle;

# Remove each directory        
$badrc = 0;
$index = 0;
foreach my $directory (@Dir) {
    # Print removing directory message with directory name
    $Verbose && printIMsg("IMsgrmsrdirRemovingDir", $directory); 

    $Trace && 
        print STDERR "Calling CT::SR::delete_directory($directory)\n";

    $rc = CT::SR::delete_directory($Tree_handle, $directory,
            $Opt_Recursive); 

    $Trace && 
        print STDERR "CT::SR::delete_directory return code: $rc)\n";

    $rc = error_check("sr_delete_directory", $rc, $Directory[$index]);

    # Store the worst return code, and continue to process 
    if ($rc == SR_CLI_REGISTRY_ERROR) { 
        $badrc = $rc; 
        last;
    }

    # Save the first bad return code
    if (($rc != 0) && ($badrc == 0)) { $badrc = $rc; }

    $index++;
}

($badrc == 0) || error_exit($badrc);

# Cleanup 
$rc = term_session($Tree_handle, $Mount_point);

exit $rc; 

#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line - Parse the command line for options and operands.  #
#   Set appropriate global variables as outlined below, make sure we #
#   have a valid combination of arguments / options.                 #
#   TODO: all exit -1 should go away when full support coded.        #
#                                                                    #
# Return:                                                            #
#   $rc   0                  Command line parsed fine, no problem.   #
#         SR_CLI_BAD_FLAG    Command line contained a bad flag.      #
#         SR_CLI_BAD_OPERAND Command line missing an operand.        #
#   @directory          Array of directories to remove.              #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Recursive     output   True (-r) remove recursively         #
#                               everything including and below dir.  #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my(@directory, $goodrc, $badrc);
my %opts = ();

# Process the command line
if (!&getopts('hRTV', \%opts )) {        # Gather options; if errors
    &print_usage;                        # display proper usage
    return SR_CLI_BAD_FLAG;              # return nogood - bad flag 
}

if ($#ARGV < 0 && !defined $opts{h}) {   # If no operands then
    &print_usage;                        # display proper usage 
    return SR_CLI_BAD_OPERAND;           # return nogood - bad operand
}

# Get the arguments
# Should all be directory names to be removed
@directory = @ARGV;                      

# See which options were specified

if (defined $opts{h}) {                  # -h, help request  
    &print_usage;                        # print usage statement
    exit(0);                             # all done with good return!
}

# TODO: SRDesign Defect 47752
#   Requesting a new sr_delete_entry function which would have a 
#   recursive flag, and sr_delete_directory be changed to only support
#   deleting directories (no tables) and have a force flag like 
#   sr_create_directory not a recursive flag.  sr_delete_entry should
#   have a recursive flag. If this happens, rmsrdir should drop support
#   of -r and -R and add support for -p.  Also a new rmsr command would
#   need to be written that should accept a -r and -R for recursive.

if (defined $opts{R}) {                 #  -R remove recursively 
    $Opt_Recursive = $TRUE;             # including non-empty
}

if (defined $opts{V}) {                 # -V verbose 
    $Verbose = $TRUE;
}

if (defined $opts{T}) {                 # -T trace
    $Trace = $TRUE;
}

return (0, @directory);                 # return success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# error_check:                                                       #
#   Checks the return code from the SR function.  If an error is     #
#   detected appropriate error messages will be displayed and        #
#   SR CLI return code set.                                          #
#                                                                    #
# Parameters:                                                        #
#   $sr_function  - Name of the SR function that was called and      #
#                   whose error code we are checking.                #
#   $sr_rc        - SR function return code.                         #
#   $directory    - Name of the directory to be removed.             #
#                                                                    #
# Return values:                                                     #
#   None.                                                            #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($sr_function, $sr_rc, $directory) = @_;
my $rc = 0;

if ($sr_rc != 0) { 
    if ($sr_rc == SR_NO_PERMISSION) {  
        printEMsg("EMsgrmsrdirPermissionError", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NO_DIRECTORY) {
        printEMsg("EMsgrmsrdirBadDirPath", $directory); 
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_DIRECTORY_NOT_EMPTY) { 
        printEMsg("EMsgrmsrdirDirNotEmpty", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_TABLES_LOCKED) {
        printEMsg("EMsgrmsrdirTablesLocked", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    else {
        # With a registry error, report the problem and quit
        printEMsg("EMsgrmsrdirRemoveDirError", $directory);
        printCEMsg("EMsgSRcliSRCommandFailure", $sr_function, $sr_rc);
        $rc = SR_CLI_REGISTRY_ERROR;
    }
}

return ($rc);
}   # end error_check


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
&printIMsg("IMsgrmsrdirUsage");
}   # end print_usage


#--------------------------------------------------------------------#
# End File                                                           #
#--------------------------------------------------------------------#
